using System;
using System.Collections.Generic;
using System.Text;

using NetServ.Net.Json;

using System.Net;
using System.IO;

using System.Windows.Forms;



namespace VoliaStat
{

    public interface IVoliaInfo
    {
        bool Get(string path,out long var);
        bool Get(string path,out string var);
        bool Get(string path);
    }



    class VoliaInfoClass:IVoliaInfo
    {

        string _url;
        JsonObject _data;
        bool _iserror;

        public const string TIMESTAMP = "timestamp";
        public const string DELIM = ".";
        //const string URL = "https://stat.voliacable.com:8443/ktvinet/vapi/jstat.jsp";
        const string URL = "https://stat.volia.com:8443/ktvinet/vapi/jstat.jsp";



        public const string  ROOT = "root";


        public bool IsError
        {
            get
            {   return _iserror;
            }
        }

        public VoliaInfoClass(string username,string password)
        {
            _url = string.Format("{0}?code={1}&pass={2}",URL,username,password);
            _data = null;
            _iserror= false;
        
        }

        private void AddTimestamp()
        {
            if (_data==null) return;
            _data.Add(TIMESTAMP, string.Format("{0:dd}.{0:MM}.{0:yy} {0:HH}:{0:mm}:{0:ss} ",DateTime.Now));


        }



        public void SetError(Exception error)
        {
            _data = new JsonObject();
            JsonObject err;
            int count = 0;
            while(error!=null)
            {   
                err = new JsonObject();
                err.Add("Message",error.Message);
                err.Add("Source",error.Source);
                err.Add("Stack",error.StackTrace);
                err.Add("Target",error.TargetSite.ToString());
                   
                _data.Add(string.Format("Error{0}",count),err);
                count++;
                error = error.InnerException;
            }
            _iserror = true;
            AddTimestamp();
        }



        public void Fetch()
        {
            _iserror = false;

            try
            {
                //string text = File.ReadAllText(@"c:\DATA\-WORK\vs2005\VoliaStat2\VoliaStat2\json.txt");
                
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };  
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
                HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                string text = ResponseToString(response);
                 
                JsonParser parser = new JsonParser(new StringReader(text), true);
                _data = (JsonObject)parser.ParseObject();
                AddTimestamp();
                
            }
            catch(Exception error)
            {
                SetError(error);
            }

        }







        object Find(string path)
        {
            string[] p = path.Split(DELIM.ToCharArray());
            object e = _data;
            foreach(string s in p)
            {   
                if (e==null) return null;
                if (e is JsonObject)
                {
                    if (!((JsonObject)e).ContainsKey(s))
                    {   e = null;
                    } else
                    {   e = ((JsonObject)e)[s];
                    }
                    continue;
                }
                if (e is JsonArray)
                {
                    int i =atoi(s); 
                    if ( (((JsonArray)e).Count<=i) || (i<0))
                    {   e = null;
                    } else
                    {   e = ((JsonArray)e)[atoi(s)];
                    }
                    continue;
                }
                throw new  Exception("VoliaInfoClass.Get : unsupported type");
            }
            return e;
        
        }


        public bool Get(string path,out long var)
        {
            var = 0;
            object e = Find(path);
            if ( (e is  JsonArray) || (e is JsonObject) ) e=null;
            if (e!=null)
            {
                try
                {   var = long.Parse(e.ToString());
                }
                catch
                {}
            }
            return  (e!=null);

        }

        public bool Get(string path)
        {
            return  (Find(path)!=null);

        }

        public bool Get(string path,out string var)
        {
            var = "";
            object e = Find(path);
            if ( (e is  JsonArray) || (e is JsonObject) ) 
            {   
                if (e is JsonArray)
                {
                    var = "array 0.."+((JsonArray)e).Count;
                }
                if (e is JsonObject)
                {
                    var="";
                    string delim=", ";
                    foreach (string key in ((JsonObject)e).Keys) var+=key+delim;
                    var = var.Trim(delim.ToCharArray());
                }
            } else
            {
                if (e!=null)  var = e.ToString();
            }
            return  (e!=null);

        }

        public static int atoi(string str)
        {
            int r=0;
            try
            {   r = int.Parse(str);
            }
            catch
            {}
            return r;
        }


        string ResponseToString(HttpWebResponse response)
        {
            string result = "";
            byte[] buf = new byte[8192];
            Stream resStream = response.GetResponseStream();
            string tempString = null;
            int count = 0;
            int i;
            Encoding ascii = Encoding.UTF8;//.GetEncoding(1251);
            while (true)
            {
                count = resStream.Read(buf, 0, buf.Length);
                if (count == 0) break;
                for (i = 0; i < count; i++) if (buf[i] < 16) buf[i] = 32;
                tempString = ascii.GetString(buf, 0, count);
                result += tempString;
                
            }
            return result;
        }









    }
}
